import sys
import os
import ast
from collections import Counter
from datetime import datetime
from PyQt5.QtWidgets import (
    QApplication, QMainWindow, QWidget, QPushButton, QLabel, QInputDialog,
    QMessageBox, QVBoxLayout, QHBoxLayout, QDialog, QFormLayout, QTextEdit, QTableWidget, QTableWidgetItem
)
from PyQt5.QtCore import Qt

from util import camera
from util import public_tools as tool
from service import hr_service as hr

ADMIN_LOGIN = False
import os

import os
# ...（其他import后面补充）
from PyQt5.QtWidgets import QTableWidget, QTableWidgetItem
# 获取 clock 文件夹的绝对路径

LOCK_RECORD_FILE = r"D:\code\pythonProject intelligent punch card system\16\clock\data\lock_record.txt"
WORK_TIME_FILE = r"D:\code\pythonProject intelligent punch card system\16\clock\data\work_time.txt"


print("LOCK_RECORD_FILE1:", LOCK_RECORD_FILE)  # 应该显示 D:\code\pythonProject intelligent punch card system\16\clock\data\lock_record.txt
# 数据文件路径



EMPLOYEE_WORK_HOURS = {}

def get_lock_record():
    print("LOCK_RECORD_FILE path:", LOCK_RECORD_FILE)
    if not os.path.exists(LOCK_RECORD_FILE):
        print("File not exists!")
        return {}
    with open(LOCK_RECORD_FILE, encoding="utf-8") as f:
        content = f.read()
        # print("lock_record.txt raw content:", repr(content))  # 重点：打印原始内容
        try:
            return ast.literal_eval(content)
        except Exception as e:
            print("Error reading lock_record.txt:", e)
            return {}
def get_work_time():
    """获取work_time.txt中的作息时间，找不到则返回默认时间"""
    if not os.path.exists(WORK_TIME_FILE):
        return "08:00:00", "18:00:00"
    with open(WORK_TIME_FILE, encoding="utf-8") as f:
        txt = f.read().strip()
        if "/" in txt:
            start, end = txt.split("/")
            return start, end
        return "08:00:00", "18:00:00"

def infer_work_times(lock_record):
    """自动推算作息时间"""
    time_morning = []
    time_evening = []
    days = set()
    for times in lock_record.values():
        for t in times:
            d = t.split()[0]
            days.add(d)
    days = sorted(days)[-30:]  # 最近30天
    for name, times in lock_record.items():
        day_map = {}
        for t in times:
            d, tm = t.split()
            if d not in day_map:
                day_map[d] = []
            day_map[d].append(tm)
        for d in days:
            if d in day_map:
                am = min(day_map[d])  # 最早
                pm = max(day_map[d])  # 最晚
                time_morning.append(am)
                time_evening.append(pm)
    def most_common_time(times):
        times = [t[:5] for t in times]
        counter = Counter(times)
        return counter.most_common(1)[0][0] + ":00" if times else "08:00:00"
    morning = most_common_time(time_morning) if time_morning else "08:00:00"
    evening = most_common_time(time_evening) if time_evening else "18:00:00"
    return morning, evening

def calculate_work_hours(lock_record):
    """遍历所有历史打卡记录，统计每个员工累计上班时长（小时）"""
    result = {}
    for name, records in lock_record.items():
        days = {}
        for r in records:
            date_str, time_str = r.split()
            if date_str not in days:
                days[date_str] = []
            days[date_str].append(time_str)
        total_hours = 0.0
        for day, times in days.items():
            if len(times) >= 2:
                t1 = datetime.strptime(day + " " + min(times), "%Y-%m-%d %H:%M:%S")
                t2 = datetime.strptime(day + " " + max(times), "%Y-%m-%d %H:%M:%S")
                hours = (t2 - t1).seconds / 3600.0
                total_hours += hours
            elif len(times) == 1:
                total_hours += 0.5  # 只有一次打卡算半小时
        result[name] = total_hours
    return result

def show_message(title, text):
    msg = QMessageBox()
    msg.setWindowTitle(title)
    msg.setText(text)
    msg.setStyleSheet("font-size:16px;")
    msg.exec_()

def center_window(window):
    qr = window.frameGeometry()
    cp = window.screen().availableGeometry().center()
    qr.moveCenter(cp)
    window.move(qr.topLeft())

class LoginDialog(QDialog):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.setWindowTitle("管理员登录")
        self.setFixedSize(350, 180)
        center_window(self)
        self.setStyleSheet("""
            QDialog { background: #f5f5f5;}
            QLabel, QLineEdit { font-size: 16px;}
            QPushButton { font-size: 16px; padding: 6px 24px;}
        """)
        from PyQt5.QtWidgets import QLineEdit
        self.username = QLineEdit()
        self.password = QLineEdit()
        self.password.setEchoMode(QLineEdit.Password)
        form = QFormLayout()
        form.addRow("账号：", self.username)
        form.addRow("密码：", self.password)
        self.btnLogin = QPushButton("登录")
        self.btnCancel = QPushButton("取消")
        hbox = QHBoxLayout()
        hbox.addWidget(self.btnLogin)
        hbox.addWidget(self.btnCancel)
        vbox = QVBoxLayout()
        vbox.addLayout(form)
        vbox.addLayout(hbox)
        self.setLayout(vbox)
        self.btnLogin.clicked.connect(self.login)
        self.btnCancel.clicked.connect(self.reject)

    def login(self):
        global ADMIN_LOGIN
        username = self.username.text().strip()
        password = self.password.text().strip()
        if hr.valid_user(username, password):
            ADMIN_LOGIN = True
            show_message("登录成功", f"{username} 登录成功！")
            self.accept()
        else:
            show_message("错误", "账号或密码错误，请重新输入！")

class EmployeeManagementDialog(QDialog):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.setWindowTitle("员工管理")
        self.setFixedSize(350, 220)
        center_window(self)
        self.setStyleSheet("""
            QDialog { background: #f5f5f5;}
            QPushButton { font-size: 16px; padding: 7px 28px;}
        """)
        layout = QVBoxLayout()
        self.btnAdd = QPushButton("录入新员工")
        self.btnDel = QPushButton("删除员工")
        self.btnBack = QPushButton("返回")
        layout.addWidget(self.btnAdd)
        layout.addWidget(self.btnDel)
        layout.addWidget(self.btnBack)
        self.setLayout(layout)
        self.btnAdd.clicked.connect(self.add_employee)
        self.btnDel.clicked.connect(self.del_employee)
        self.btnBack.clicked.connect(self.reject)

    def add_employee(self):
        name, ok = QInputDialog.getText(self, "录入新员工", "请输入新员工姓名（输入0取消）：")
        if ok and name.strip() != "0" and name.strip():
            code = hr.add_new_employee(name.strip())
            show_message("拍照", "请面对摄像头，敲击三次回车键完成拍照！")
            camera.register(code)
            show_message("成功", "录入成功！")

    def del_employee(self):
        report = hr.get_employee_report()
        show_message("员工名单", report)
        id, ok = QInputDialog.getInt(self, "删除员工", "请输入要删除的员工编号（输入0取消）：", 0, 0)
        if ok and id > 0:
            if hr.check_id(id):
                verification = tool.randomNumber(4)
                inputVer, ok2 = QInputDialog.getText(self, "验证码", f"[{verification}] 请输入验证码：")
                if ok2 and str(verification) == inputVer.strip():
                    hr.remove_employee(id)
                    show_message("成功", f"{id}号员工已删除！")
                else:
                    show_message("错误", "验证码有误，操作取消")
            else:
                show_message("错误", "无此员工，操作取消")

class RecordDialog(QDialog):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.setWindowTitle("查看记录")
        self.setFixedSize(400, 300)
        center_window(self)
        self.setStyleSheet("""
            QDialog { background: #f5f5f5;}
            QPushButton { font-size: 16px; padding: 7px 28px;}
        """)
        layout = QVBoxLayout()
        self.btnList = QPushButton("查看员工列表")
        self.btnRecord = QPushButton("查看打卡记录")
        self.btnBack = QPushButton("返回")
        layout.addWidget(self.btnList)
        layout.addWidget(self.btnRecord)
        layout.addWidget(self.btnBack)
        self.setLayout(layout)
        self.btnList.clicked.connect(self.show_list)
        self.btnRecord.clicked.connect(self.show_record)
        self.btnBack.clicked.connect(self.reject)

    def show_list(self):
        report = hr.get_employee_report()
        dlg = QTextDialog("员工名单", report, self)
        dlg.exec_()

    def show_record(self):
        report = hr.get_record_all()
        dlg = QTextDialog("打卡记录", report, self)
        dlg.exec_()

class ReportConfigDialog(QDialog):
    def __init__(self, parent=None, morning="08:00:00", evening="18:00:00"):
        super().__init__(parent)
        self.setWindowTitle("报表设置")
        self.setFixedSize(350, 200)
        center_window(self)
        self.setStyleSheet("""
            QDialog { background: #f5f5f5;}
            QLabel, QLineEdit { font-size: 16px;}
            QPushButton { font-size: 16px; padding: 7px 28px;}
        """)
        layout = QFormLayout()
        self.work_time = QInputDialog.getText(self, "上班时间", "请设置上班时间(如08:00:00)：", text=morning)[0]
        self.close_time = QInputDialog.getText(self, "下班时间", "请设置下班时间(如18:00:00)：", text=evening)[0]
        self.btnSet = QPushButton("设置")
        self.btnBack = QPushButton("返回")
        hbox = QHBoxLayout()
        hbox.addWidget(self.btnSet)
        hbox.addWidget(self.btnBack)
        vbox = QVBoxLayout()
        lbl1 = QLabel(f"当前上班时间：{morning}")
        lbl2 = QLabel(f"当前下班时间：{evening}")
        vbox.addWidget(lbl1)
        vbox.addWidget(lbl2)
        vbox.addLayout(hbox)
        self.setLayout(vbox)
        self.btnSet.clicked.connect(self.set_time)
        self.btnBack.clicked.connect(self.reject)

    def set_time(self):
        work_time = self.work_time.strip()
        close_time = self.close_time.strip()
        if not tool.valid_time(work_time):
            show_message("错误", "上班时间格式错误，请重新输入")
            return
        if not tool.valid_time(close_time):
            show_message("错误", "下班时间格式错误，请重新输入")
            return
        hr.save_work_time(work_time, close_time)
        show_message("成功", f"设置完成，上班时间：{work_time}, 下班时间为：{close_time}")

class CheckReportDialog(QDialog):
    def __init__(self, parent=None, morning="08:00:00", evening="18:00:00"):
        super().__init__(parent)
        self.setWindowTitle("考勤报表")
        self.setFixedSize(400, 400)
        center_window(self)
        self.setStyleSheet("""
            QDialog { background: #f5f5f5;}
            QLabel { font-size: 18px; font-weight: bold;}
            QPushButton { font-size: 15px; padding: 5px 24px;}
        """)
        layout = QVBoxLayout()
        title = QLabel("考勤报表功能菜单")
        layout.addWidget(title)
        layout.addSpacing(8)

        self.btnDay = QPushButton("日报")
        self.btnMonth = QPushButton("月报")
        self.btnConfig = QPushButton("报表设置")
        self.btnWorkRank = QPushButton("上班时长排行榜")
        self.btnBack = QPushButton("返回")

        for btn in [self.btnDay, self.btnMonth, self.btnConfig, self.btnWorkRank, self.btnBack]:
            layout.addWidget(btn, alignment=Qt.AlignCenter)

        self.setLayout(layout)
        self.btnDay.clicked.connect(self.day_report)
        self.btnMonth.clicked.connect(self.month_report)
        self.btnConfig.clicked.connect(lambda: self.report_config(morning, evening))
        self.btnWorkRank.clicked.connect(self.show_work_time_rank)
        self.btnBack.clicked.connect(self.reject)
        self.btnLateEarlyRank = QPushButton("迟到/早退排行榜")
        # ...（后略）
        for btn in [self.btnDay, self.btnMonth, self.btnConfig, self.btnWorkRank, self.btnLateEarlyRank, self.btnBack]:
            layout.addWidget(btn, alignment=Qt.AlignCenter)
        # ...
        self.btnLateEarlyRank.clicked.connect(self.show_late_early_rank)

    def show_late_early_rank(self):
        dlg = LateEarlyRankDialog(self)
        dlg.exec_()

    def day_report(self):
        date, ok = QInputDialog.getText(self, "日报", "输入查询日期(2008-08-08),输入0则查询今天：")
        if ok:
            if date == "0":
                hr.get_today_report()
            elif tool.valid_date(date):
                hr.get_day_report(date)
            else:
                show_message("错误", "日期格式有误，请重新输入！")

    def month_report(self):
        date, ok = QInputDialog.getText(self, "月报", "输入查询月份(2008-08),输入0则查询上个月：")
        if ok:
            if date == "0":
                hr.get_pre_month_report()
            elif tool.valid_year_month(date):
                hr.get_month_report(date)
            else:
                show_message("错误", "日期格式有误，请重新输入！")

    def report_config(self, morning, evening):
        dlg = ReportConfigDialog(self, morning, evening)
        dlg.exec_()

    def show_work_time_rank(self):
        dlg = RankDialog(self)
        dlg.exec_()


# ...（其他代码保持不变）

class LateEarlyRankDialog(QDialog):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.setWindowTitle("迟到/早退排行榜")
        self.setFixedSize(480, 360)
        center_window(self)
        self.setStyleSheet("""
            QDialog { background: #f5f5f5;}
            QTableWidget { font-size: 15px;}
            QLabel { font-size: 18px; font-weight: bold;}
        """)
        layout = QVBoxLayout()
        label = QLabel("员工迟到/早退排行榜")
        layout.addWidget(label)
        self.table = QTableWidget(0, 3)
        self.table.setHorizontalHeaderLabels(["姓名", "迟到次数", "早退次数"])
        self.table.horizontalHeader().setStretchLastSection(True)
        self.table.verticalHeader().setVisible(False)
        layout.addWidget(self.table)
        self.setLayout(layout)
        self.load_and_refresh_data()

    def load_and_refresh_data(self):
        from service import hr_service as hr
        rank = hr.get_late_early_rank()
        # 排序：按迟到+早退总次数降序
        data = sorted(rank.items(), key=lambda x: (x[1][0] + x[1][1]), reverse=True)
        self.table.setRowCount(len(data))
        for i, (name, (late, early)) in enumerate(data):
            self.table.setItem(i, 0, QTableWidgetItem(str(name)))
            self.table.setItem(i, 1, QTableWidgetItem(str(late)))
            self.table.setItem(i, 2, QTableWidgetItem(str(early)))
class RankDialog(QDialog):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.setWindowTitle("员工上班时长排行榜")
        self.setFixedSize(420, 350)
        center_window(self)
        self.setStyleSheet("""
            QDialog { background: #f5f5f5;}
            QTableWidget { font-size: 15px;}
            QLabel { font-size: 18px; font-weight: bold;}
        """)
        layout = QVBoxLayout()
        label = QLabel("员工上班时长排行榜")
        layout.addWidget(label)
        self.table = QTableWidget(0, 2)
        self.table.setHorizontalHeaderLabels(["姓名", "上班时长 (小时)"])
        self.table.horizontalHeader().setStretchLastSection(True)
        self.table.verticalHeader().setVisible(False)
        layout.addWidget(self.table)
        self.setLayout(layout)
        self.load_and_refresh_data()

    def load_and_refresh_data(self):
        # 每次打开窗口都重新加载统计
        lock_record = get_lock_record()
        print("lock_record:", lock_record)
        EMPLOYEE_WORK_HOURS.clear()
        EMPLOYEE_WORK_HOURS.update(calculate_work_hours(lock_record))
        data = sorted(EMPLOYEE_WORK_HOURS.items(), key=lambda x: x[1], reverse=True)
        self.table.setRowCount(len(data))
        for i, (name, hour) in enumerate(data):
            self.table.setItem(i, 0, QTableWidgetItem(str(name)))
            self.table.setItem(i, 1, QTableWidgetItem(f"{hour:.2f}"))

class QTextDialog(QDialog):
    def __init__(self, title, text, parent=None):
        super().__init__(parent)
        self.setWindowTitle(title)
        self.setFixedSize(500, 400)
        center_window(self)
        self.setStyleSheet("""
            QDialog { background: #f5f5f5;}
            QTextEdit { font-size: 15px; background: #fafafa;}
        """)
        layout = QVBoxLayout()
        self.textEdit = QTextEdit()
        self.textEdit.setReadOnly(True)
        self.textEdit.setText(text)
        layout.addWidget(self.textEdit)
        self.setLayout(layout)

class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("MR智能视频打卡系统")
        self.setFixedSize(500, 440)
        center_window(self)
        self.setStyleSheet("""
            QMainWindow { background: #f5f5f5;}
            QLabel { font-size:28px; color: #222; font-weight: bold;}
            QPushButton {
                font-size: 18px; padding: 10px 0px; margin: 10px 30px;
                background-color: #f0f0f0; color: #222; border: 1px solid #cacaca; border-radius: 2px;
            }
            QPushButton:hover {
                background-color: #e2e2e2; color: #222;
            }
        """)

        label = QLabel("MR智能视频打卡系统", alignment=Qt.AlignCenter)
        layout = QVBoxLayout()
        layout.addWidget(label)

        work_morning, work_evening = get_work_time()
        lock_record = get_lock_record()
        if lock_record:
            auto_morning, auto_evening = infer_work_times(lock_record)
        else:
            auto_morning, auto_evening = work_morning, work_evening

        self.lblWorkTime = QLabel(f"系统作息时间：{work_morning} - {work_evening}\n自动推算上班时间：{auto_morning}，下班时间：{auto_evening}")
        self.lblWorkTime.setStyleSheet("font-size:16px;color:#444;")
        layout.addWidget(self.lblWorkTime)

        self.btnClock = QPushButton("打卡")
        self.btnRecord = QPushButton("查看记录")
        self.btnEmployee = QPushButton("员工管理")
        self.btnReport = QPushButton("考勤报表")
        self.btnExit = QPushButton("退出")

        layout.addWidget(self.btnClock)
        layout.addWidget(self.btnRecord)
        layout.addWidget(self.btnEmployee)
        layout.addWidget(self.btnReport)
        layout.addWidget(self.btnExit)

        widget = QWidget()
        widget.setLayout(layout)
        self.setCentralWidget(widget)

        self.btnClock.clicked.connect(self.face_clock)
        self.btnRecord.clicked.connect(self.check_record)
        self.btnEmployee.clicked.connect(self.employee_management)
        self.btnReport.clicked.connect(lambda: self.check_report(auto_morning, auto_evening))
        self.btnExit.clicked.connect(self.close)

    def face_clock(self):
        show_message("打卡", "请正面对准摄像头进行打卡\n回车键代表确认")
        name = camera.clock_in()
        if name is not None:
            hr.add_lock_record(name)
            show_message("打卡成功", f"{name} 打卡成功！")
        else:
            show_message("打卡失败", "打卡失败")

    def check_record(self):
        global ADMIN_LOGIN
        if ADMIN_LOGIN:
            dlg = RecordDialog(self)
            dlg.exec_()
        else:
            dlg = LoginDialog(self)
            dlg.exec_()

    def employee_management(self):
        global ADMIN_LOGIN
        if ADMIN_LOGIN:
            dlg = EmployeeManagementDialog(self)
            dlg.exec_()
        else:
            dlg = LoginDialog(self)
            dlg.exec_()

    def check_report(self, morning, evening):
        global ADMIN_LOGIN
        if ADMIN_LOGIN:
            dlg = CheckReportDialog(self, morning, evening)
            dlg.exec_()
        else:
            dlg = LoginDialog(self)
            dlg.exec_()

if __name__ == "__main__":
    hr.load_emp_data()
    app = QApplication(sys.argv)
    win = MainWindow()
    win.show()
    sys.exit(app.exec_())